package com.mrroman.linksender;

import java.awt.Color;
import java.awt.GraphicsEnvironment;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyVetoException;
import java.beans.VetoableChangeListener;
import java.io.File;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.logging.Logger;

import com.mrroman.linksender.ioc.Init;
import com.mrroman.linksender.ioc.Locales;
import com.mrroman.linksender.ioc.Log;
import com.mrroman.linksender.ioc.Name;
import com.mrroman.linksender.settings.beanutils.FontStyles;
import javax.swing.filechooser.FileSystemView;

@Name("linksender.Configuration")
public class Configuration extends com.mrroman.linksender.settings.Settings<Configuration> {

    private static final long serialVersionUID = 1426477255620776047L;
    private static final String confFile = System.getProperty("user.home") + File.separator + ".linksender";
    //private Properties properties = new Properties();
    @Log
    private Logger logger;
    @Locales
    private ResourceBundle messages;

    @Init
    public void init() {
        this.load("configuration.xml");
        this.addVetoableChangeListener(new MyVetoableChangeListener());
        Properties sp = System.getProperties();
        if (getProxyHost() != null && getProxyPort() != null && getProxyPort() > 0) {
        sp.setProperty("http.proxyHost", getProxyHost());
        sp.setProperty("http.proxyPort", ""+getProxyPort());
        sp.setProperty("https.proxyHost", getProxyHost());
        sp.setProperty("https.proxyPort", ""+getProxyPort());
        }
    }

    public Configuration() {
    }

    @Override
    public String applicationName() {
        return "linksender";
    }

    public String homepage() {
        return "http://code.google.com/p/linksender/";
    }
    
    /********************************************************************
     * VetoableChangeListener
     ********************************************************************/
    String[] fontNames = null;

    private class MyVetoableChangeListener implements VetoableChangeListener {

        @Override
        public void vetoableChange(PropertyChangeEvent evt) throws PropertyVetoException {
            if (PROP_ADDRESS.equals(evt.getPropertyName())) {
                String value = (String) evt.getNewValue();
                if (!value.matches("(([0-1]?[0-9]{1,2}\\.)|(2[0-4][0-9]\\.)|(25[0-5]\\.)){3}(([0-1]?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5]))")) {
                    throw new PropertyVetoException("IP address out of range", evt);
                }
            } else if (PROP_AUTHORLABELFONTNAME.equals(evt.getPropertyName()) ||
                    PROP_DATELABELFONTNAME.equals(evt.getPropertyName()) ||
                    PROP_MESSAGELABELFONTNAME.equals(evt.getPropertyName())) {
                String value = ((String) evt.getNewValue()).toLowerCase();
                if (fontNames == null) {
                    GraphicsEnvironment gEnv = GraphicsEnvironment.getLocalGraphicsEnvironment();
                    fontNames = gEnv.getAvailableFontFamilyNames();
                }
                boolean found = false;
                for (String font : fontNames) {
                    if (font.toLowerCase().equals(value)) {
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    throw new PropertyVetoException("Font name not found", evt);
                }
            } else if (PROP_AUTHORLABELFONTSIZE.equals(evt.getPropertyName()) ||
                    PROP_DATELABELFONTSIZE.equals(evt.getPropertyName()) ||
                    PROP_MESSAGELABELFONTSIZE.equals(evt.getPropertyName())) {
                Integer value = (Integer) evt.getNewValue();
                if (value < 3 || value > 100) {
                    throw new PropertyVetoException("Font size out of range", evt);
                }
            } else if (PROP_NICK.equals(evt.getPropertyName())) {
                String value = (String) evt.getNewValue();
                if (value.trim().equals("")) {
                    throw new PropertyVetoException("Nick must not be empty", evt);
                }
            } else if (PROP_PORT.equals(evt.getPropertyName())) {
                Integer value = (Integer) evt.getNewValue();
                if (value < 1024 || value > 65535) {
                    throw new PropertyVetoException("Port value out of range", evt);
                }
            }
        }
    }
    /********************************************************************
     * Properties, setters & getters
     ********************************************************************/
    private String messageLabelFontName = "Arial";
    public static final String PROP_MESSAGELABELFONTNAME = "messageLabelFontName";

    /**
     * Get the value of messageLabelFontName
     *
     * @return the value of messageLabelFontName
     */
    public String getMessageLabelFontName() {
        return messageLabelFontName;
    }

    /**
     * Set the value of messageLabelFontName
     *
     * @param messageLabelFontName new value of messageLabelFontName
     * @throws java.beans.PropertyVetoException
     */
    public void setMessageLabelFontName(String messageLabelFontName) throws java.beans.PropertyVetoException {
        String oldMessageLabelFontName = this.messageLabelFontName;
        vetoableChangeSupport.fireVetoableChange(PROP_MESSAGELABELFONTNAME, oldMessageLabelFontName, messageLabelFontName);
        this.messageLabelFontName = messageLabelFontName;
        propertyChangeSupport.firePropertyChange(PROP_MESSAGELABELFONTNAME, oldMessageLabelFontName, messageLabelFontName);
    }
    private int messageLabelFontSize = 10;
    public static final String PROP_MESSAGELABELFONTSIZE = "messageLabelFontSize";

    /**
     * Get the value of messageLabelFontSize
     *
     * @return the value of messageLabelFontSize
     */
    public int getMessageLabelFontSize() {
        return messageLabelFontSize;
    }

    /**
     * Set the value of messageLabelFontSize
     *
     * @param messageLabelFontSize new value of messageLabelFontSize
     * @throws java.beans.PropertyVetoException
     */
    public void setMessageLabelFontSize(int messageLabelFontSize) throws java.beans.PropertyVetoException {
        int oldMessageLabelFontSize = this.messageLabelFontSize;
        vetoableChangeSupport.fireVetoableChange(PROP_MESSAGELABELFONTSIZE, oldMessageLabelFontSize, messageLabelFontSize);
        this.messageLabelFontSize = messageLabelFontSize;
        propertyChangeSupport.firePropertyChange(PROP_MESSAGELABELFONTSIZE, oldMessageLabelFontSize, messageLabelFontSize);
    }
    private FontStyles messageLabelFontStyle = FontStyles.PLAIN;
    public static final String PROP_MESSAGELABELFONTSTYLE = "messageLabelFontStyle";

    /**
     * Get the value of messageLabelFontStyle
     *
     * @return the value of messageLabelFontStyle
     */
    public FontStyles getMessageLabelFontStyle() {
        return messageLabelFontStyle;
    }

    /**
     * Set the value of messageLabelFontStyle
     *
     * @param messageLabelFontStyle new value of messageLabelFontStyle
     * @throws java.beans.PropertyVetoException
     */
    public void setMessageLabelFontStyle(FontStyles messageLabelFontStyle) throws java.beans.PropertyVetoException {
        FontStyles oldMessageLabelFontStyle = this.messageLabelFontStyle;
        vetoableChangeSupport.fireVetoableChange(PROP_MESSAGELABELFONTSTYLE, oldMessageLabelFontStyle, messageLabelFontStyle);
        this.messageLabelFontStyle = messageLabelFontStyle;
        propertyChangeSupport.firePropertyChange(PROP_MESSAGELABELFONTSTYLE, oldMessageLabelFontStyle, messageLabelFontStyle);
    }
    private String authorLabelFontName = "Arial";
    public static final String PROP_AUTHORLABELFONTNAME = "authorLabelFontName";

    /**
     * Get the value of authorLabelFontName
     *
     * @return the value of authorLabelFontName
     */
    public String getAuthorLabelFontName() {
        return authorLabelFontName;
    }

    /**
     * Set the value of authorLabelFontName
     *
     * @param authorLabelFontName new value of authorLabelFontName
     * @throws java.beans.PropertyVetoException
     */
    public void setAuthorLabelFontName(String authorLabelFontName) throws java.beans.PropertyVetoException {
        String oldAuthorLabelFontName = this.authorLabelFontName;
        vetoableChangeSupport.fireVetoableChange(PROP_AUTHORLABELFONTNAME, oldAuthorLabelFontName, authorLabelFontName);
        this.authorLabelFontName = authorLabelFontName;
        propertyChangeSupport.firePropertyChange(PROP_AUTHORLABELFONTNAME, oldAuthorLabelFontName, authorLabelFontName);
    }
    private FontStyles authorLabelFontStyle = FontStyles.BOLD;
    public static final String PROP_AUTHORLABELFONTSTYLE = "authorLabelFontStyle";

    /**
     * Get the value of authorLabelFontStyle
     *
     * @return the value of authorLabelFontStyle
     */
    public FontStyles getAuthorLabelFontStyle() {
        return authorLabelFontStyle;
    }

    /**
     * Set the value of authorLabelFontStyle
     *
     * @param authorLabelFontStyle new value of authorLabelFontStyle
     * @throws java.beans.PropertyVetoException
     */
    public void setAuthorLabelFontStyle(FontStyles authorLabelFontStyle) throws java.beans.PropertyVetoException {
        FontStyles oldAuthorLabelFontStyle = this.authorLabelFontStyle;
        vetoableChangeSupport.fireVetoableChange(PROP_AUTHORLABELFONTSTYLE, oldAuthorLabelFontStyle, authorLabelFontStyle);
        this.authorLabelFontStyle = authorLabelFontStyle;
        propertyChangeSupport.firePropertyChange(PROP_AUTHORLABELFONTSTYLE, oldAuthorLabelFontStyle, authorLabelFontStyle);
    }
    private int authorLabelFontSize = 10;
    public static final String PROP_AUTHORLABELFONTSIZE = "authorLabelFontSize";

    /**
     * Get the value of authorLabelFontSize
     *
     * @return the value of authorLabelFontSize
     */
    public int getAuthorLabelFontSize() {
        return authorLabelFontSize;
    }

    /**
     * Set the value of authorLabelFontSize
     *
     * @param authorLabelFontSize new value of authorLabelFontSize
     * @throws java.beans.PropertyVetoException
     */
    public void setAuthorLabelFontSize(int authorLabelFontSize) throws java.beans.PropertyVetoException {
        int oldAuthorLabelFontSize = this.authorLabelFontSize;
        vetoableChangeSupport.fireVetoableChange(PROP_AUTHORLABELFONTSIZE, oldAuthorLabelFontSize, authorLabelFontSize);
        this.authorLabelFontSize = authorLabelFontSize;
        propertyChangeSupport.firePropertyChange(PROP_AUTHORLABELFONTSIZE, oldAuthorLabelFontSize, authorLabelFontSize);
    }
    private int dateLabelFontSize = 8;
    public static final String PROP_DATELABELFONTSIZE = "dateLabelFontSize";

    /**
     * Get the value of dateLabelFontSize
     *
     * @return the value of dateLabelFontSize
     */
    public int getDateLabelFontSize() {
        return dateLabelFontSize;
    }

    /**
     * Set the value of dateLabelFontSize
     *
     * @param dateLabelFontSize new value of dateLabelFontSize
     * @throws java.beans.PropertyVetoException
     */
    public void setDateLabelFontSize(int dateLabelFontSize) throws java.beans.PropertyVetoException {
        int oldDateLabelFontSize = this.dateLabelFontSize;
        vetoableChangeSupport.fireVetoableChange(PROP_DATELABELFONTSIZE, oldDateLabelFontSize, dateLabelFontSize);
        this.dateLabelFontSize = dateLabelFontSize;
        propertyChangeSupport.firePropertyChange(PROP_DATELABELFONTSIZE, oldDateLabelFontSize, dateLabelFontSize);
    }
    private FontStyles dateLabelFontStyle = FontStyles.PLAIN;
    public static final String PROP_DATELABELFONTSTYLE = "dateLabelFontStyle";

    /**
     * Get the value of dateLabelFontStyle
     *
     * @return the value of dateLabelFontStyle
     */
    public FontStyles getDateLabelFontStyle() {
        return dateLabelFontStyle;
    }

    /**
     * Set the value of dateLabelFontStyle
     *
     * @param dateLabelFontStyle new value of dateLabelFontStyle
     * @throws java.beans.PropertyVetoException
     */
    public void setDateLabelFontStyle(FontStyles dateLabelFontStyle) throws java.beans.PropertyVetoException {
        FontStyles oldDateLabelFontStyle = this.dateLabelFontStyle;
        vetoableChangeSupport.fireVetoableChange(PROP_DATELABELFONTSTYLE, oldDateLabelFontStyle, dateLabelFontStyle);
        this.dateLabelFontStyle = dateLabelFontStyle;
        propertyChangeSupport.firePropertyChange(PROP_DATELABELFONTSTYLE, oldDateLabelFontStyle, dateLabelFontStyle);
    }
    private String dateLabelFontName = "Arial";
    public static final String PROP_DATELABELFONTNAME = "dateLabelFontName";

    /**
     * Get the value of dateLabelFontName
     *
     * @return the value of dateLabelFontName
     */
    public String getDateLabelFontName() {
        return dateLabelFontName;
    }

    /**
     * Set the value of dateLabelFontName
     *
     * @param dateLabelFontName new value of dateLabelFontName
     * @throws java.beans.PropertyVetoException
     */
    public void setDateLabelFontName(String dateLabelFontName) throws java.beans.PropertyVetoException {
        String oldDateLabelFontName = this.dateLabelFontName;
        vetoableChangeSupport.fireVetoableChange(PROP_DATELABELFONTNAME, oldDateLabelFontName, dateLabelFontName);
        this.dateLabelFontName = dateLabelFontName;
        propertyChangeSupport.firePropertyChange(PROP_DATELABELFONTNAME, oldDateLabelFontName, dateLabelFontName);
    }
    private Color popupPanelColor = new Color(255, 255, 192);
    public static final String PROP_POPUPPANELCOLOR = "popupPanelColor";

    /**
     * Get the value of popupPanelColor
     *
     * @return the value of popupPanelColor
     */
    public Color getPopupPanelColor() {
        return popupPanelColor;
    }

    /**
     * Set the value of popupPanelColor
     *
     * @param popupPanelColor new value of popupPanelColor
     */
    public void setPopupPanelColor(Color popupPanelColor) {
        Color oldPopupPanelColor = this.popupPanelColor;
        this.popupPanelColor = popupPanelColor;
        propertyChangeSupport.firePropertyChange(PROP_POPUPPANELCOLOR, oldPopupPanelColor, popupPanelColor);
    }
    private Color privateMessageColor = new Color(192, 255, 192);
    public static final String PROP_PRIVATEMESSAGECOLOR = "privateMessageColor";

    /**
     * Get the value of privateMessageColor
     *
     * @return the value of privateMessageColor
     */
    public Color getPrivateMessageColor() {
        return privateMessageColor;
    }

    /**
     * Set the value of privateMessageColor
     *
     * @param privateMessageColor new value of privateMessageColor
     */
    public void setPrivateMessageColor(Color privateMessageColor) {
        Color oldPrivateMessageColor = this.privateMessageColor;
        this.privateMessageColor = privateMessageColor;
        propertyChangeSupport.firePropertyChange(PROP_PRIVATEMESSAGECOLOR, oldPrivateMessageColor, privateMessageColor);
    }
    private Color errorMessageColor = new Color(255, 192, 192);
    public static final String PROP_ERRORMESSAGECOLOR = "errorMessageColor";

    /**
     * Get the value of errorMessageColor
     *
     * @return the value of errorMessageColor
     */
    public Color getErrorMessageColor() {
        return errorMessageColor;
    }

    /**
     * Set the value of errorMessageColor
     *
     * @param errorMessageColor new value of errorMessageColor
     */
    public void setErrorMessageColor(Color errorMessageColor) {
        Color oldErrorMessageColor = this.errorMessageColor;
        this.errorMessageColor = errorMessageColor;
        propertyChangeSupport.firePropertyChange(PROP_ERRORMESSAGECOLOR, oldErrorMessageColor, errorMessageColor);
    }
    private Color infoMessageColor = new Color(180, 230, 255);
    public static final String PROP_INFOMESSAGECOLOR = "infoMessageColor";

    /**
     * Get the value of infoMessageColor
     *
     * @return the value of infoMessageColor
     */
    public Color getInfoMessageColor() {
        return infoMessageColor;
    }

    /**
     * Set the value of infoMessageColor
     *
     * @param infoMessageColor new value of infoMessageColor
     */
    public void setInfoMessageColor(Color infoMessageColor) {
        Color oldInfoMessageColor = this.infoMessageColor;
        this.infoMessageColor = infoMessageColor;
        propertyChangeSupport.firePropertyChange(PROP_INFOMESSAGECOLOR, oldInfoMessageColor, infoMessageColor);
    }

    private String proxyHost = System.getProperties().getProperty("http.proxyHost");
    public static final String PROP_PROXYHOST = "proxyHost";

    /**
     * Get the value of proxyHost
     *
     * @return the value of proxyHost
     */
    public String getProxyHost() {
        return proxyHost;
    }

    /**
     * Set the value of proxyHost
     *
     * @param proxyHost new value of proxyHost
     * @throws java.beans.PropertyVetoException
     */
    public void setProxyHost(String proxyHost) throws java.beans.PropertyVetoException {
        String oldProxyHost = this.proxyHost;
        vetoableChangeSupport.fireVetoableChange(PROP_PROXYHOST, oldProxyHost, proxyHost);
        this.proxyHost = proxyHost;
        propertyChangeSupport.firePropertyChange(PROP_PROXYHOST, oldProxyHost, proxyHost);
    }

    private Integer proxyPort = Integer.getInteger("http.proxyPort");
    
    public static final String PROP_PROXYPORT = "proxyPort";

    /**
     * Get the value of proxyPort
     *
     * @return the value of proxyPort
     */
    public Integer getProxyPort() {
        return proxyPort;
    }

    /**
     * Set the value of proxyPort
     *
     * @param proxyPort new value of proxyPort
     * @throws java.beans.PropertyVetoException
     */
    public void setProxyPort(Integer proxyPort) throws java.beans.PropertyVetoException {
        Integer oldProxyPort = this.proxyPort;
        vetoableChangeSupport.fireVetoableChange(PROP_PROXYPORT, oldProxyPort, proxyPort);
        this.proxyPort = proxyPort;
        propertyChangeSupport.firePropertyChange(PROP_PROXYPORT, oldProxyPort, proxyPort);
    }

    private String address = "224.5.6.7";
    public static final String PROP_ADDRESS = "address";

    /**
     * Get the value of address
     *
     * @return the value of address
     */
    public String getAddress() {
        return address;
    }

    /**
     * Set the value of address
     *
     * @param address new value of address
     * @throws java.beans.PropertyVetoException
     */
    public void setAddress(String address) throws java.beans.PropertyVetoException {
        String oldAddress = this.address;
        vetoableChangeSupport.fireVetoableChange(PROP_ADDRESS, oldAddress, address);
        this.address = address;
        propertyChangeSupport.firePropertyChange(PROP_ADDRESS, oldAddress, address);
    }
    private Integer port = 6789;
    public static final String PROP_PORT = "port";

    /**
     * Get the value of port
     *
     * @return the value of port
     */
    public Integer getPort() {
        return port;
    }

    /**
     * Set the value of port
     *
     * @param port new value of port
     * @throws java.beans.PropertyVetoException
     */
    public void setPort(Integer port) throws java.beans.PropertyVetoException {
        Integer oldPort = this.port;
        vetoableChangeSupport.fireVetoableChange(PROP_PORT, oldPort, port);
        this.port = port;
        propertyChangeSupport.firePropertyChange(PROP_PORT, oldPort, port);
    }
    private boolean loopbackMode = true;
    public static final String PROP_LOOPBACKMODE = "loopbackMode";

    /**
     * Get the value of loopbackMode
     *
     * @return the value of loopbackMode
     */
    public boolean isLoopbackMode() {
        return loopbackMode;
    }

    /**
     * Set the value of loopbackMode
     *
     * @param loopbackMode new value of loopbackMode
     */
    public void setLoopbackMode(boolean loopbackMode) {
        boolean oldLoopbackMode = this.loopbackMode;
        this.loopbackMode = loopbackMode;
        propertyChangeSupport.firePropertyChange(PROP_LOOPBACKMODE, oldLoopbackMode, loopbackMode);
    }
    protected String nick = "anonymous";
    public static final String PROP_NICK = "nick";

    /**
     * Get the value of nick
     *
     * @return the value of nick
     */
    public String getNick() {
        return nick;
    }

    /**
     * Set the value of nick
     *
     * @param nick new value of nick
     * @throws java.beans.PropertyVetoException
     */
    public void setNick(String nick) throws java.beans.PropertyVetoException {
        String oldNick = this.nick;
        vetoableChangeSupport.fireVetoableChange(PROP_NICK, oldNick, nick);
        this.nick = nick;
        propertyChangeSupport.firePropertyChange(PROP_NICK, oldNick, nick);
    }
    
    private boolean hideGroupMessages = false;
    public static final String PROP_HIDEGROUPMESSAGES = "hideGroupMessages";

    /**
     * Get the value of hideGroupMessages
     *
     * @return the value of hideGroupMessages
     */
    public boolean isHideGroupMessages() {
        return hideGroupMessages;
    }

    /**
     * Set the value of hideGroupMessages
     *
     * @param hideGroupMessages new value of hideGroupMessages
     */
    public void setHideGroupMessages(boolean hideGroupMessages) {
        boolean oldHideGroupMessages = this.hideGroupMessages;
        this.hideGroupMessages = hideGroupMessages;
        propertyChangeSupport.firePropertyChange(PROP_HIDEGROUPMESSAGES, oldHideGroupMessages, hideGroupMessages);
    }
    
    private boolean sendToTwitter = false;
    public static final String PROP_SENDTOTWITTER = "sendToTwitter";

    /**
     * Get the value of hideGroupMessages
     *
     * @return the value of hideGroupMessages
     */
    public boolean isSendToTwitter() {
        return sendToTwitter;
    }

    /**
     * Set the value of hideGroupMessages
     *
     * @param hideGroupMessages new value of hideGroupMessages
     */
    public void setSendToTwitter(boolean sendToTwitter) {
        boolean oldSendToTwitter = this.sendToTwitter;
        this.sendToTwitter = sendToTwitter;
        propertyChangeSupport.firePropertyChange(PROP_SENDTOTWITTER, oldSendToTwitter, sendToTwitter);
    }

    private String outputDirectory = FileSystemView.getFileSystemView().getHomeDirectory().toString();
    public static final String PROP_OUTPUTDIRECTORY = "outputDirectory";

    /**
     * Get the value of outputDirectory
     *
     * @return the value of outputDirectory
     */
    public String getOutputDirectory() {
        return outputDirectory;
    }

    /**
     * Set the value of outputDirectory
     *
     * @param outputDirectory new value of outputDirectory
     * @throws java.beans.PropertyVetoException
     */
    public void setOutputDirectory(String outputDirectory) throws java.beans.PropertyVetoException {
        String oldOutputDirectory = this.outputDirectory;
        vetoableChangeSupport.fireVetoableChange(PROP_OUTPUTDIRECTORY, oldOutputDirectory, outputDirectory);
        this.outputDirectory = outputDirectory;
        propertyChangeSupport.firePropertyChange(PROP_OUTPUTDIRECTORY, oldOutputDirectory, outputDirectory);
    }

}

